import * as cesium from 'cesium';

/**
 * 将cesium.Cartesian3对象转换为经纬度坐标
 * @param {cesium.Cartesian3} cartesian3 三维笛卡尔坐标
 * @param {cesium.Viewer} viewer 三维视图对象
 * @returns {Object} 经纬度坐标对象
 */
export const cartesian3ToLng = (cartesian3, viewer) => {
    // 获得椭球体
    // console.log(viewer)
    const ellipsoid = viewer.scene.globe.ellipsoid;
    // console.log("ellipsoid",ellipsoid)
    // 获得弧度制数据
    const cartographic = ellipsoid.cartesianToCartographic(cartesian3);
    // 转换为度制数据
    const lng = cesium.Math.toDegrees(cartographic.longitude);
    const lat = cesium.Math.toDegrees(cartographic.latitude);
    const height = cartographic.height;

    return { lng, lat, height };
}

/**
 * 将经纬度坐标转换为cesium.Cartesian3对象
 * @param {Object} lnglat 经纬度坐标对象
 * @returns {cesium.Cartesian3} 三维笛卡尔坐标
 */
export const lnglatToCartesian3 = (lnglat) => {
    const { lng, lat, height } = lnglat;
    const cartesian3 = new cesium.Cartesian3.fromDegrees(lng, lat, height);
    return cartesian3;
}

/**
 * 经纬度数组转换为cesium.Cartesian3数组
 * @param {Array<{lng,lat,height}>} positionLngs : 经纬度数组
 * @returns {Array} 三维笛卡尔坐标数组
 */
export const lnglatPositionsToCartesian3s = (positionLngs) => {
    const result = []
    if (positionLngs.length) {
        positionLngs.forEach(position => {
            const { lng, lat, height } = position
            result.push(lng, lat, height)
        })
        return cesium.Cartesian3.fromDegreesArrayHeights(result)
    } else {
        return result
    }
}

/**
 * 屏幕坐标转笛卡尔3
 * @param {cesium.Viewer} viewer : viewer
 * @param {cesium.Cartesian2} position2d : 笛卡尔2维
 * @returns {cesium.Cartesian3} 三维笛卡尔坐标
 */
export const screenPositionToCartesian3 = (viewer, position) => {
    //viewer.camera.getPickRay(position)是将屏幕坐标转换为射线
    //viewer.scene.globe.pick可以将射线投射到地球表面，返回投射点的笛卡尔坐标
    //注意这里屏幕坐标一定要在球上，否则生成出的cartesian对象是undefined
    let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(position), viewer.scene);
    if (!cartesian) {
        //如果没有在球上，则使用相机投影
        //viewer.scene.camera.pickEllipsoid可以将屏幕坐标投射到地球表面，返回投射点的笛卡尔坐标
        cartesian = viewer.scene.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
    }
    return cartesian
}

/**
 * @param {tx,ty,tz,rx,ry,rz,scale} params : 变换对象,tx为位置坐标
 * @param {cesium.Cesium3DTileset} tileset : 3dtiles对象
 * 
 */

// 更新3dtiles的模型矩阵
export const update3dtilesMaxtrix = (params, tileset) => {
    //根据经纬度控制模型的位置
    let position = cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
    let m = cesium.Transforms.eastNorthUpToFixedFrame(position);

    //旋转
    //  根据角度，获取到3阶旋转矩阵
    let mx = cesium.Matrix3.fromRotationX(cesium.Math.toRadians(params.rx));
    let my = cesium.Matrix3.fromRotationY(cesium.Math.toRadians(params.ry));
    let mz = cesium.Matrix3.fromRotationZ(cesium.Math.toRadians(params.rz));
    //   根据3阶旋转矩阵，获取到4阶旋转矩阵
    let rotationX = cesium.Matrix4.fromRotationTranslation(mx);
    let rotationY = cesium.Matrix4.fromRotationTranslation(my);
    let rotationZ = Cescesiumum.Matrix4.fromRotationTranslation(mz);

    //旋转、平移矩阵相乘
    cesium.Matrix4.multiply(m, rotationX, m);
    cesium.Matrix4.multiply(m, rotationY, m);
    cesium.Matrix4.multiply(m, rotationZ, m);

    //   构造缩放矩阵
    const _scale = cesium.Matrix4.fromUniformScale(params.scale);
    cesium.Matrix4.multiply(m, _scale, m);
    //赋值给tileset
    tileset._root.transform = m;
};

//
export const changeControl = (viewer) => {
    //修改倾斜视角的操作
    viewer.scene.screenSpaceCameraController.tiltEventTypes = [
        cesium.CameraEventType.LEFT_DRAG,
    ];
    //修改缩放视角的操作
    viewer.scene.screenSpaceCameraController.zoomEventTypes = [
        cesium.CameraEventType.WHEEL,
        cesium.CameraEventType.MIDDLE_DRAG,
    ];
    //设置拖拽
    viewer.scene.screenSpaceCameraController.rotateEventTypes = [

        cesium.CameraEventType.LEFT_DRAG,
    ]
}
//获取唯一码 时间不可能重复
export function getPlotCode() {
    const date = new Date();
    let code = date.getFullYear() + "";
    code += date.getMonth() + 1;
    code += date.getDate();
    code += date.getHours();
    code += date.getMinutes();
    code += date.getSeconds();
    code += date.getMilliseconds();
    return code;
  }